#ifndef __TZSP2PCAP_HPP__
#define __TZSP2PCAP_HPP__

#include <iostream>
#include <vector>
#include <list>
#include <unistd.h>
#include <sys/time.h>
#include <fstream>

#include <string>
#include <atomic>

#include <thread>
#include <mutex>
#include <condition_variable>
#include "json/json.h"

#define TUN_DEV_NAME_LENGTH 32
#define MAX_TUN_NR 100
#define RECV_BUFFER_LENGTH 10000
#define TZSP_MAX_FIELDS 32

#define TZSP_FLAG_NOFIELDS  0x01
#define TZSP_FLAG_NODATA    0x02

#define TZSP_ENC_ETH        0x01

#define TZSP_HDR_PAD        0x00
#define TZSP_HDR_END        0x01
using namespace std;

// PCAP 文件头结构体
struct pcap_file_header {
	uint32_t magic_number;
	uint16_t version_major;
	uint16_t version_minor;
	int32_t thiszone;
	uint32_t sigfigs;
	uint32_t snaplen;
	uint32_t network;
};

// PCAP 数据包头部结构体
struct pcap_pkthdr {
	uint32_t time_sec;
	uint32_t time_usec;
	uint32_t caplen;
	uint32_t len;
};
// PCAP 文件信息
typedef struct pcap_file_save_struct {
	pcap_file_save_struct(string tmp_path, string dst_path)
	{
		size = 0;
		count = 0;
		file_path_tmp = tmp_path;
		file_path = dst_path;
		outFile.open(file_path_tmp, ios::binary);
	}
	~pcap_file_save_struct()
	{
                close_rename_file();
	}
        void close_rename_file()
        {
                if (outFile.is_open()) {
                        outFile.close();
                }
                if (0 == access(file_path_tmp.c_str(), F_OK)) {
                        rename(file_path_tmp.c_str(), file_path.c_str());
                }
        }
	string file_path;
	string file_path_tmp;
	ofstream outFile;
	uint64_t count;
	uint64_t size;
} pcap_file_save_t;

struct tzspheader {
	unsigned short version:8;
	unsigned short flags:4;
	unsigned short type:4;
	unsigned short enc:16;
};

typedef struct src_package {
public:
	src_package(ssize_t len_in = 0)
	{
		datalen = len_in;
		data = nullptr;
		if (datalen > 0 ) {
			data = new uint8_t[datalen];
		}
	}
	~src_package()
	{
		if (datalen > 0 && data) {
			delete[] data;
		}
	}
	timeval current_time;
	ssize_t datalen;
	uint8_t *data;
} srcpkg_t;

struct tzspfield {
	uint8_t tag;
	uint8_t len;
	char *data;
};

typedef struct tzsp_package {
	struct tzspheader *tzsphdr;
	//tagged fields
	struct tzspfield *fields[TZSP_MAX_FIELDS];
	unsigned short num_fields;
	//data
	timeval current_time;
	char *data;
	size_t datalen;
} tzsppkg_t;

class tzsptap2pcap
{
private:
	/* data */
	string tzsp_dev_ip;
	ssize_t pcap_single_size;
	string pcap_save_top_dir;// 此对象保存pcap的主目录(指定文件目录/$tzsp_dev_ip， 如：/tmp/192.168.1.1)
	string pcap_save_back_dir; //此对象保存pcap的动态目录(指定文件目录/$tzsp_dev_ip/年-月-日-时, 如：/tmp/192.168.1.1/2025-04-23-14)

	list<srcpkg_t *> srcpkg_list; //TSZP 数据list
	mutex srcpkg_list_mtx;
	condition_variable srcpkg_list_cv;
	uint32_t srcpkg_list_count; //SZP 数据list 元素个数

	pcap_file_save_t *pcap_writting; //当前正在写入的文件
	pcap_file_save_t *pcap_new_write;//新的要写入的文件
	mutex pcap_writting_mtx;

	atomic<bool> stopThreadFlag;
	thread t_check_time_up_directory;
	thread t_pare_tzsp_to_pcap;
public:
	int pkg_flag;
	uint64_t pcap_file_size;
        list <pcap_file_save_t *> pcap_files;
	tzsptap2pcap(/* args */);
	tzsptap2pcap(string &dev_ip, char* &pcap_sigle_size_str);
	~tzsptap2pcap();
	void set_pcap_save_top_dir(const char *dir_path);
	void srcpkg_list_push_back(uint8_t *_data, ssize_t _len, timeval c_time); //向list中添加元素

	void thread_pare_tzsp_to_pcap();
	void thread_no_pare_to_pcap();
	void thread_check_time_up_directory();
	void stop_thread();
	void start_thread();
	void compose_open_file(timeval _ts);
	void write_srcpkg_t_to_pcap_file(srcpkg_t &pkg);
	void write_tzsp_to_pcap_file(tzsppkg_t &pkg);
	void state();
        Json::Value pcap_files_formatJSON();
        string pcap_files_formatJSON_string();
};

#endif /* __TZSP2PCAP_HPP__ */
